package com.warmlight.voicepacket.widget;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.util.Log;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class AudioPCMPlayer {
    private static final String TAG = AudioPCMPlayer.class.getSimpleName();

    private AudioTrack mAudioTrack;
    private int minPlayBufferSize = 0;
    private byte[] playerBuffer;
    private boolean playingstart = false;
    private PlayThread playThread = null;
    private static AudioPCMPlayer mInstance;
    private String PCMPath = "";
    private AudioPCMPlayer() {
//        this.soundTouch = soundtouch;
        initPCMPlayer();
    }

    public static AudioPCMPlayer getInstance() {
        if(mInstance == null){
            synchronized (AudioPCMPlayer.class){
                if(mInstance == null){
                    mInstance = new AudioPCMPlayer();
                }
            }
        }
        return mInstance;
    }

    private void initPCMPlayer(){
        minPlayBufferSize = AudioTrack.getMinBufferSize(8000,
                AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);

        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
                AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
                minPlayBufferSize * 3, AudioTrack.MODE_STREAM);
        playerBuffer = new byte[minPlayBufferSize * 3];
    }

    /**
     * AudioPlayer播放完毕的监听回调
     */
    private AudioCompletedListener mAudioCompletedListener;

    public boolean isPlaying() {
        return playingstart;
    }

    public interface AudioCompletedListener{
        void AudioCompleted();
    }
    public void setOnAudioCompletedListener(AudioCompletedListener listener){
        mAudioCompletedListener = listener;
    }

    public void startPlay(String fileName) {

        if (PCMPath.equals(fileName)){
            if (playingstart){
                playingstart = false;
                return;
            }else{

            }

        }else{
            if (playingstart){
                stopPlay();
            }
            else{
//                stopPlay();
            }
        }
        PCMPath = fileName;

//        if (playThread != null && playThread.isAlive()) {
//            return;
//        }

        if (minPlayBufferSize != 0) {
            mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
                    AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
                    minPlayBufferSize * 3, AudioTrack.MODE_STREAM);
            mAudioTrack.play();
            playingstart = true;
            playThread = new PlayThread(fileName);
            playThread.start();
        }
    }

    public void stopPlay(boolean wait) {
        playingstart = false;
        if (mAudioTrack != null && playingstart) {
            mAudioTrack.stop();
            mAudioTrack.release();
        }
        if (playThread != null && playThread.isAlive()) {
            playThread.interrupt();
        }
        if (wait) {
            try {
                playThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        playThread = null;

    }

    public void stopPlay() {
        stopPlay(true);
    }

    class PlayThread extends Thread {
        //这里是用不到的合成所需
//        public static final String TUNED = "tuned";
        private FileInputStream playInputStream = null;
//        private FileOutputStream recordOutputStream = null;
        private String fileName;
//        private String tuendFileName;

        PlayThread(String fileName) {
            this.fileName = fileName;
            if (fileName != null) {
                try {
//                    playInputStream = context.openFileInput(fileName);
//                    String recordFile = FileUtils.getRecordFile(context);
//                    File file = new File(recordFile,fileName);
                    playInputStream = new FileInputStream(fileName);
                } catch (FileNotFoundException e) {
                }
            }
        }

        @Override
        public void run() {
//            int totalPCMSamples = 0;
//            int totalSTSamples = 0;
//            int receiveSTSamples = 0;

//            createTunedFile();

            try {
//                String recordFile = FileUtils.getRecordFile(context);
//                File file = new File(recordFile,fileName);
                playInputStream = new FileInputStream(fileName);
//                playInputStream = context.openFileInput(tuendFileName);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            //playingstart 控制播放和暂停
            while (playingstart && playInputStream != null) {
                int len = 0;
                try {
                    len = playInputStream.read(playerBuffer, 0,
                            playerBuffer.length);

                } catch (IOException e) {
                    e.printStackTrace();
                }

                if (len == -1) {
                    Log.d(TAG, "file read finish!");
                    try {
                        playInputStream.close();
//                        String recordFile = FileUtils.getRecordFile(context);
//                        File file = new File(recordFile,fileName);
//                        playInputStream = new FileInputStream(fileName);
//                        playInputStream = context.openFileInput(tuendFileName);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {
                        playingstart = false;
                        try {

                            mAudioTrack.stop();
                            mAudioTrack.release();
                            playingstart = false;
                            interrupt();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                        if (mAudioCompletedListener != null){
                            mAudioCompletedListener.AudioCompleted();
                        }
                    }

                } else if (len != 0) {
                    if (playingstart) {
                        mAudioTrack.write(playerBuffer, 0, len);
                    }else{
                        playingstart = false;
                        try {

                            mAudioTrack.stop();
                            mAudioTrack.release();
                            playingstart = false;
                            interrupt();
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                    }
                }

            }




            if (playInputStream != null) {
                try {
                    playInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

//        private void createTunedFile() {
//            tuendFileName = TUNED + fileName;
//            try {
//                recordOutputStream = context.openFileOutput(tuendFileName,
//                        Context.MODE_PRIVATE);
//
//                int totalPCMSamples = 0;
//                int totalSTSamples = 0;
//
//                int receiveSTSamples = 0;
//
//                while (playInputStream != null) {
//                    int len = playInputStream.read(playerBuffer, 0,
//                            playerBuffer.length);
//
//                    if (len == -1) {
//                        break;
//                    }
//
//                    int inputSamples = len / ((16 * 1) / 8);
//                    totalPCMSamples += inputSamples;
//
//                    try {
//                        Log.d(TAG, "input ST pcm size :" + inputSamples);
//                        soundTouch.putBytes(playerBuffer);
//                        do {
//                            receiveSTSamples = soundTouch.getBytes(playerBuffer);
//                            totalSTSamples += receiveSTSamples;
//                            Log.d(TAG, "receive ST pcm samples :"
//                                    + receiveSTSamples);
//                            if (receiveSTSamples != 0) {
//                                recordOutputStream.write(playerBuffer, 0, receiveSTSamples);
//                                recordOutputStream.flush();
//                            }
//                        } while (receiveSTSamples != 0);
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                }
//
//                do {
//                    receiveSTSamples = soundTouch.getBytes(playerBuffer);
//                    Log.d(TAG, "receive remainder ST samples:"
//                            + receiveSTSamples);
//                    totalSTSamples += receiveSTSamples;
//
//                    if (receiveSTSamples != 0) {
//                        try {
//                            recordOutputStream.write(playerBuffer, 0,
//                                    receiveSTSamples * ((16 * 1) / 8));
//                            recordOutputStream.flush();
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        }
//
//                    }
//                } while (receiveSTSamples != 0);
//                Log.d(TAG, "Total input pcm samples:" + totalPCMSamples);
//                Log.d(TAG, "total receive ST samoles:" + totalSTSamples);
//                try {
//                    recordOutputStream.close();
//                    playInputStream.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            } catch (FileNotFoundException e) {
//                e.printStackTrace();
//            } catch (IOException e1) {
//                e1.printStackTrace();
//            }
//        }
    }
}
